var version = 'v1.0.2'
var resources = [
  '/',
  '/index.html',
  '/converter.css',
  '/converter.js',
  '/icon512.png',
  '/manifest.json',
]

var log = (...args) => console.log(version, ...args)
class SW {
  constructor(version, resources = [], fallbackUrl) {
    this.version = version;
    this.resources = resources;
    this.fallbackUrl = fallbackUrl;
    this.addEventListener()
    console.group('version: ' + version)
  }
  addEventListener() {
    self.addEventListener('install', this.install)
    self.addEventListener('activate', this.activate)
    self.addEventListener('message', this.message)
    self.addEventListener('fetch', this.fetch)
    self.addEventListener('sync', this.sync)
    self.addEventListener('push', this.push)
  }
  /**
   * 安装缓存 - 初始化和更新都触发
   */
  install = (e) => {
    log('install')
    e.waitUntil(addResourcesToCache(this.version, this.resources))
  }
  /**
   * 更新时，触发，删除历史缓存
   * @param {*} e 
   */
  activate = (e) => {
    log('activate')
    e.waitUntil([enableNavigationPreload(), clients.claim(), deleteResourcesFromCache(this.version)])
  }
  message = (e) => {
    log('message', e)
    if (e.data && e.data.type === 'skipWaiting') {
      self.skipWaiting(); // 触发立即更新
    }
  }
  fetch = (e) => {
    log('fetch', e.request.url)
    e.respondWith(readCacheFirst({
      version: this.version,
      request: e.request,
      preloadResponse: e.preloadResponse,
      fallbackUrl: this.fallbackUrl
    }))
  }
  sync = () => {
    log('sync')
  }
  push = () => {
    log('push')
  }
}
new SW(version, resources)

// 启用导航预加载
async function enableNavigationPreload() {
  if (self.registration.navigationPreload) {
    await self.registration.navigationPreload.enable();
  }
};

// 删除非当前版本的缓存
async function deleteResourcesFromCache(version) {
  const deleteKeys = (await caches.keys()).filter(key => key != version);
  return Promise.all(deleteKeys.map(async key => await caches.delete(key)))
}

// 
async function addResourcesToCache(version, resources) {
  const cache = await caches.open(version);
  await cache.addAll(resources);
};


async function readCacheFirst({ request, version, fallbackUrl, preloadResponse }) {
  const cache = await caches.open(version)
  const responseFromCache = await cache.match(request)
  if (responseFromCache) {
    return responseFromCache
  }

  const responseFromPreload = await preloadResponse
  if (responseFromPreload) {
    return responseFromPreload
  }

  try {
    const responseFromServe = await fetch(request)
    cache.put(request, responseFromServe.clone())
    return responseFromServe
  } catch (error) {
    if (fallbackUrl) {
      const fallbackResponse = await cache.match(fallbackUrl);
      if (fallbackResponse) {
        return fallbackResponse;
      }
    }
    return new Response("Network error happened", {
      status: 408,
      headers: { "Content-Type": "text/plain" },
    });
  }
}
// install  缓存资源 - 初次安装和更新后会重走
// self.addEventListener()